﻿/*
 * Created by SharpDevelop.
 * User: lin
 * Date: 2019/4/18
 * Time: 22:44
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using SuperSocket.SocketBase.Protocol;
using Modbus;

namespace supersocketest1
{
	/// <summary>
	/// Description of FormServer.
	/// </summary>
	public partial class FormServer : Form
	{
		SortedList<string, AppSession> list = new SortedList<string, AppSession>();
		AppServer appServer;
		public FormServer()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			//SuperSocket提供一个内置的通信协议“命令行协议”定义每个请求都必须以回车换行("\r\n")结尾
            //\r\n: 回车(13)换行(10) 即0D0A
			//bool b = Environment.NewLine == "\r\n";
			//byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Environment.NewLine);
			//string ss = "";
			//for (int i = 0; i < bytes.Length; i++)
			//{
			//    ss += string.Format("{0:X2},", bytes[i]);
			//}
			//MessageBox.Show(b.ToString()+" " +ss);
			
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
		}
		
		private void Form1_Load(object sender, EventArgs e)
		{

		}
		
		
		private void xx(AppSession arg1, BinaryRequestInfo arg2)
		{
			throw new NotImplementedException();
		}
		
		private void AppServer_SessionClosed(AppSession session, SuperSocket.SocketBase.CloseReason value)
		{
        //MessageBox.Show("客户端已关闭:" + value);
			string sessionIp = string.Format("{0}:{1}", session.RemoteEndPoint.Address, session.RemoteEndPoint.Port);
			list.Remove(sessionIp);
			this.Invoke(new MethodInvoker(() => {
				richTextBox1.AppendText(string.Format("客户端已关闭：{0},端口：{1}，原因：{2}\n", session.RemoteEndPoint.Address, session.RemoteEndPoint.Port, value));
				cboClientList.Items.Remove(sessionIp);
			}));           
		}
		
		/// <summary>
		/// 接收来自客户端的内容，客户端发送的内容以\r\n作为结束符
		/// </summary>
		/// <param name="session"></param>
		/// <param name="requestInfo"></param>
		private void AppServer_NewRequestReceived(AppSession session, SuperSocket.SocketBase.Protocol.StringRequestInfo requestInfo)
		{
        /*
        SuperSocket中内置的命令行协议是用空格来分割请求的key和参，当客户端发送数据到服务器端时
        "Login kerry 123456"+Environment.NewLine
        SuperSocket服务器会收到一个StringRequestInfo实例，属性为：
        key:"Login"
        Body:"kerry 123456"
        Parameters:"kerry 123456"
        SuperSocket默认结束符
        */
			string body = requestInfo.Body;
			string charSet = session.Charset.BodyName;
			DateTime dt = session.LastActiveTime;
			//Socket client = session.SocketSession.Client;
			//string key = requestInfo.Key;
			string key = session.CurrentCommand;
			//string paras = string.Join(",", requestInfo.Parameters);
			this.Invoke(new MethodInvoker(() => {
				StringBuilder sb = new StringBuilder(key);
				if (body.Length > 0) {
					sb.Append(" " + body);
				}
				sb.Append("\n发送时间：" + dt.ToString("yyyy-MM-dd HH:mm:ss"));
				sb.Append(",字符编码：" + charSet);
				sb.Append("\n");
				richTextBox1.AppendText(sb.ToString());
				//richTextBox1.AppendText(string.Format("{0}--key:{1},body:{2},paras:{3}\n发送时间：{4},字符编码：{5}\n", session.RemoteEndPoint.Address+":"+ session.RemoteEndPoint.Port,
				//    key, body, paras,  dt.ToString("yyyy-MM-dd HH:mm:ss"), charSet));
			}));           
			//byte[] sendBuffer = { 48, 49, 50, 51, 65, 66, 67, 97, 98, 99 };
			//session.Send("abc123你好");
		}
		
		private void AppServer_NewSessionConnected(AppSession session)
		{
			//MessageBox.Show(session.GetType().ToString() + "," + session.RemoteEndPoint.Address);
			//MessageBox.Show(session.SessionID + "," + session.RemoteEndPoint.Port);
			string sessionIp = string.Format("{0}:{1}", session.RemoteEndPoint.Address, session.RemoteEndPoint.Port);
			list.Add(sessionIp, session);
			this.Invoke(new MethodInvoker(() => {
				richTextBox1.AppendText(string.Format("客户端已连接：{0},端口：{1}\n", session.RemoteEndPoint.Address, session.RemoteEndPoint.Port));
				cboClientList.Items.Add(sessionIp);
			}));
			session.Send("Welcome");
		}
		
		
		void BtnlistenClick(object sender, EventArgs e)
		{
			//使用##作为结束符 结束符协议
			//SuperSocket.SocketBase.Protocol.TerminatorReceiveFilter
			//带起止符的协议
			//SuperSocket.SocketBase.Protocol.BeginEndMarkReceiveFilter
			appServer = new AppServer();
			ServerConfig serverConfig = new ServerConfig();
			System.Net.IPHostEntry ipHost = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
			System.Net.IPAddress[] ipCollection = ipHost.AddressList;
			string ip = "";
			for (int i = 0; i < ipCollection.Length; i++) {
				if (ipCollection[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) {
					ip = ipCollection[i].ToString();
					break;
				}
			}
			//获取所有客户端连接
			//foreach (AppSession item in appServer.GetAllSessions())
			//{
			//    MessageBox.Show(item.RemoteEndPoint.Address + ":" + item.RemoteEndPoint.Port);
			//}
			//如果注释下一行代码，则默认编码格式为ASCII
			serverConfig.TextEncoding = "gbk";//gb2312
			//appServer.Config.TextEncoding
			//MessageBox.Show(ip);
			serverConfig.Ip = ip;
			this.label1.Text=ip.ToString();
			serverConfig.Port = int.Parse(this.tbxPort.Text);
			if (!appServer.Setup(serverConfig))
			//if (!appServer.Setup(ip, 2012))
 {			//if (!appServer.Setup(2012))
				MessageBox.Show("开启监听端口失败");
				return;
			}
			if (!appServer.Start()) {
				MessageBox.Show("服务器开启监听失败");
				return;
			}
			//客户端连接事件
			appServer.NewSessionConnected += AppServer_NewSessionConnected;
			//SuperSocket.SocketBase.Protocol.BinaryRequestInfo
			//appServer.NewRequestReceived += new Action<AppSession, SuperSocket.SocketBase.Protocol.BinaryRequestInfo>(xx);
			//appServer.NewMessageReceived+=
            //接收事件
			appServer.NewRequestReceived += AppServer_NewRequestReceived;
            //客户端已关闭事件
			appServer.SessionClosed += AppServer_SessionClosed;
			richTextBox1.AppendText(string.Format("服务器启动监听成功,服务器IP：{0},端口：{1}\n", appServer.Config.Ip, appServer.Config.Port));
            //MessageBox.Show("服务器启动监听成功");
	
		}
		
		void BtnSendClick(object sender, EventArgs e)
		{
			if (cboClientList.SelectedIndex == -1) {
				MessageBox.Show("请选择一个客户端对象");
				return;
			}
			if (rtxtSendMessage.Text.Length == 0) {
				MessageBox.Show("请输入发送内容！", "提示");
				rtxtSendMessage.Focus();
				return;
			}
			string sessionIp = cboClientList.Items[cboClientList.SelectedIndex].ToString();
			AppSession sessionTo = list[sessionIp];
			sessionTo.Send(rtxtSendMessage.Text);
	
		}
		
		void BtnClearClick(object sender, EventArgs e)
		{
			richTextBox1.Clear();
	
		}
	}
}

